#include "bmp.h"

// 获取 BMP 调色板数据
BMP readBMP(const char* filename) {
    BMP bmp = {0, 0, 0, NULL};

    FILE* file = fopen(filename, "rb");
    if (file == NULL) {
        return bmp;
    }

    // 读取文件头
    BMPFileHeader fileHeader;
    fread(&fileHeader, sizeof(BMPFileHeader), 1, file);

    if (fileHeader.bfType != 0x4d42) {
        goto READ_BMP_END;
    }

    // 读取信息头
    BMPInfoHeader infoHeader;
    fread(&infoHeader, sizeof(BMPInfoHeader), 1, file);

    if (infoHeader.biBitCount != 24 && infoHeader.biBitCount != 32) {
        goto READ_BMP_END;
    }

    bmp.width = infoHeader.biWidth;
    bmp.height = infoHeader.biHeight;
    bmp.bitCount = infoHeader.biBitCount;

    uint32_t size = infoHeader.biWidth * infoHeader.biHeight;

    Color* palette = (Color*)malloc(size * sizeof(Color));
    if (palette == NULL) {
        fclose(file);
        return bmp;
    }
    bmp.entry = palette;

    // 54 bytes
    fseek(file, fileHeader.bfOffBits, SEEK_SET);

    uint32_t offset = 0;
    if (infoHeader.biBitCount == 24) {
        RGB data[BUF];
        while (!feof(file)) {
            size_t bytes = fread(data, sizeof(RGB), BUF, file);
            if (bytes == 0) {
                break;
            }

            for (size_t i = 0; i < bytes; i++) {
                RGB rgb = ((RGB*)data)[i];
                Color* color = &palette[offset + i];

                color->alpha = 0xFF;
                color->red = rgb.red;
                color->green = rgb.green;
                color->blue = rgb.blue;
            }

            offset += bytes;
        }
    } else if (infoHeader.biBitCount == 32) {
        Color data[BUF];
        while (!feof(file)) {
            size_t bytes = fread(data, sizeof(Color), BUF, file);
            if (bytes == 0) {
                break;
            }

            for (size_t i = 0; i < bytes; i++) {
                palette[offset + i] = ((Color*)data)[i];
            }

            offset += bytes;
        }
    }

    for (size_t i = 0; i < bmp.height / 2; i++) {
        for (size_t j = 0; j < bmp.width; j++) {
            Color temp = palette[i * bmp.width + j];
            palette[i * bmp.width + j] = palette[(bmp.height - i - 1) * bmp.width + j];
            palette[(bmp.height - i - 1) * bmp.width + j] = temp;
        }
    }

READ_BMP_END:
    fclose(file);
    return bmp;
}
